﻿using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Drawing;
using System.Text;
using System.Web.Mvc;
using System.Net;
using System.IO;
using System.Data.Objects;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Security.Cryptography;
using System.Web.SessionState;
using System.Management;
using BugTracker.Models;
using BugTracker.Helper;

namespace BugTracker.Helper
{
    public class SessionHelper
    {
        Bug_db toget = new Bug_db();
        Session session = new Session();

        #region Variable Declarations
        private int session_idPK;
        private string session_name;
        private string session_datecreated;
        private string session_datelogout;
        private string session_time;
        private int session_useridFK;
        private int session_roleidFK;
        private string session_rolename;
        //private string session_token;
        private int session_flag;
        protected static int userID;
        protected static string fname;
        private static string rolename;
        private static string username;
        protected static int roleidFK;
        private static int sess_flag;
        protected static int ctr = 0;
        protected static int times = 0;
        public int placeholder_id;
        public string sessnid;
        private const int totalhrs = 9;
        private int timeResult;
        private string timeinHrs;

        #endregion

        #region GetBrowserType

        public string Session_GetBrowserType()
        {
            string userbrowser = HttpContext.Current.Request.Browser["Browser"];
            return userbrowser;
        }

        #endregion

        #region GetIPAddress

        public string Session_GetIPAddress()
        {
            string ipAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            if (ipAddress == null || ipAddress == "")
            {
                ipAddress = HttpContext.Current.Request.UserHostAddress;
            }
            return ipAddress;
        }
        #endregion



        #region public bool Session_ExpireWork()
        public bool Session_ExpireWork()
        {
            int regtime = 20;
            if (Session_Info().rolename == "Administrator")
            {
                if (regtime == Convert.ToInt32(GetTimeinHr()))
                {
                    return true;
                }
            }
            else if (Session_Info().rolename == "Developer")
            {
                if (regtime == Convert.ToInt32(GetTimeinHr()))
                {
                    return true;
                }
            }
            else if (Session_Info().rolename == "Quality Assurance")
            {
                if (regtime == Convert.ToInt32(GetTimeinHr()))
                {
                    return true;
                }
            }
            else if (Session_Info().rolename == "Project Manager")
            {
                if (regtime == Convert.ToInt32(GetTimeinHr()))
                {
                    return true;
                }
            }

            return false;
        }
        #endregion

        public int sesionIDPK(string pass)
        {
            string token = TheSessionId() + pass;
            var ses = (from sesn in toget.Sessions
                       where sesn.passcode == pass && sesn.sessionid_token == token
                       && sesn.session_flag == 1
                       select sesn.session_idPK).SingleOrDefault();

            return ses;
        }


        #region public bool SessionAuth(int? session_id)
        public bool SessionAuth(int? session_id)
        {

            int ses_userid = Session_Info().user_idFK;
            string today = Session_GetDateToday();
            string brows = Session_GetBrowserType();
            string sesid = TheSessionId();

            var passc = toget.Users.Find(ses_userid);
            // string token = sesid + passc.passcode;
            if (passc != null)
            {

                var m_login = (from s in toget.Sessions
                               where s.session_idPK == session_id
                                   && s.session_flag == 1
                                   //&& s.sessionid_token == token
                                   && s.session_datelogout == null
                                   && s.user_idFK == ses_userid
                                   && s.session_datecreated == today
                               select s).SingleOrDefault();

                if (m_login != null)
                {
                    if (Session_ExpireWork() == true)
                    {
                        Session_Logout(m_login.session_idPK);
                        return false;
                    }

                    if (Session_Expire(m_login.session_idPK) == true)
                    {
                        Session_Logout(m_login.session_idPK);
                        return false;
                    }

                    return true;
                }
                else
                {
                    return false;
                }
            }
            return false;
        }

        #endregion

        #region  public bool Session_Expire(int id)
        public bool Session_Expire(int id)
        {
            var ses = toget.Sessions.Find(id);

            timeinHrs = GetTimeinHr();

            timeResult = Convert.ToInt32(timeinHrs) - Convert.ToInt32(ses.session_timelogin);

            if (timeResult >= totalhrs)
            {
                return true;
            }
            else
            {
                return false;
            }

        }
        #endregion

        #region Time / Date Retriever
        public string GetTimeinHr()
        {
            string time = DateTime.Now.ToString("HH", System.Globalization.DateTimeFormatInfo.InvariantInfo);
            return time;
        }

        public string Session_GetDateToday()
        {
            string t = DateTime.Now.ToString("d/MM/yyyy");
            return t;
        }
        #endregion

        #region public bool GetSession(int? id)
        public bool GetSession(int? id)
        {
            var session_state = toget.Sessions.Find(id);

            if (session_state != null)
            {
                session_idPK = session_state.session_idPK;
                session_name = session_state.session_Name;
                session_datecreated = session_state.session_datecreated;
                //session_token = session_state.session_token.ToString();
                session_flag = session_state.session_flag;
                session_datelogout = session_state.session_datelogout;
                session_time = session_state.session_time;
                session_useridFK = session_state.user_idFK;
                session_roleidFK = session_state.role_idFK;
                session_rolename = session_state.rolename;
                //session_passcode = session_state.passcode;


                userID = session_idPK;
                roleidFK = session_roleidFK;
                rolename = session_rolename;
                sess_flag = session_state.session_flag;
                username = session_name;

                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion




        #region Session Init( int id, string passcode, Session m_session)
        public int Session_Init(int id, string passcode, Session m_session)
        {

            var session_state = toget.Users.Find(id);

            string today = Session_GetDateToday();
            string now = DateTime.Now.ToString("HH:mm:ss", System.Globalization.DateTimeFormatInfo.InvariantInfo);
            string browser = Session_GetBrowserType();
            string complete_name = session_state.first_name + ' ' + session_state.last_name;
            string size_name = complete_name.Length.ToString();
            string ip = Session_GetIPAddress();
            string sesid_token = TheSessionId();

            session.session_Name = complete_name;
            session.session_token = EncryptSession_Token(passcode).ToString();
            session.session_datecreated = today;
            session.role_idFK = session_state.role_idFK;

            session.passcode = session.passcode;
            session.ipaddress = ip;
            session.sessionid_token = sesid_token + session.passcode;
            // session.rolename = session_state.role_idFK
            session.session_time = now;
            session.user_idFK = session_state.user_idPK;
            session.browser = browser;
            session.session_flag = 1;
            session.session_timelogin = GetTimeinHr();

            sess_flag = session.session_flag;
            fname = session_state.first_name;
            rolename = session.rolename;
            roleidFK = session.role_idFK;
            username = session.session_Name;

            m_session.session_Name = session.session_Name;
            m_session.session_token = session.session_token;
            m_session.session_datecreated = session.session_datecreated;
            m_session.session_time = session.session_time;
            m_session.role_idFK = session.role_idFK;
            m_session.rolename = session.rolename;
            m_session.passcode = session.passcode;
            m_session.user_idFK = session.user_idFK;
            m_session.ipaddress = session.ipaddress;
            m_session.sessionid_token = session.sessionid_token;
            m_session.browser = session.browser;
            m_session.session_flag = session.session_flag;
            m_session.session_timelogin = session.session_timelogin;
            toget.Sessions.Add(m_session);
            toget.SaveChanges();

            return m_session.session_idPK;


        }
        #endregion

        public static string TheSessionId()
        {
            HttpSessionState ss = HttpContext.Current.Session;
            HttpContext.Current.Session["ID"] = "ID";
            var id = ss.SessionID; //(ss.SessionID);

            return id;
        }

        #region  public bool GetUserID()
        public bool GetUserID()
        {

            if (userID != 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion



        #region public Session Session_Info()
        public Session Session_Info()
        {

            string ses_browser = Session_GetBrowserType();
            string today = Session_GetDateToday();
            string sesstoken = TheSessionId();
            sessnid = sesstoken;
            var s_userid = (from uid in toget.Sessions
                            where uid.session_datelogout == null
                            && uid.session_flag == 1 && uid.session_datecreated == today
                            select uid).ToList();

            if (s_userid != null)
            {

                foreach (var u_user in s_userid)
                {

                    var pass = toget.Users.Find(u_user.user_idFK);

                    if (pass != null)
                    {
                        string name = pass.first_name + " " + pass.last_name;
                        string sestoken = sesstoken + u_user.passcode;

                        var check_log = (
                            from u in toget.Sessions
                            where u.session_datelogout == null
                            && u.user_idFK == u_user.user_idFK
                                //&& u.sessionid_token = sestoken
                            && u.session_Name == name
                            && u.session_flag == 1
                            && u.session_datecreated == today
                            select u).FirstOrDefault();

                        //session_random = BROWSER_TYPE|SESSION_IP|FLAG|58768687GFDJHDGFDF
                        if (check_log != null)
                        {
                            //if (check_log.useridFK == u_user)
                            //{
                            return check_log;
                            //}
                        }

                    }
                }
            }

            return null;

        }
        #endregion



        #region Get Role

        public string Session_GetRole()
        {
            if (Session_Info() != null)
            {
                int role_id = Session_Info().role_idFK;
                int user_id = Session_Info().user_idFK;

                var name = (from u in toget.Users
                            join r in toget.Roles on u.role_idFK equals r.role_idPK
                            where u.role_idFK == role_id && u.user_idPK == user_id
                            select r.role_name).SingleOrDefault();
                return name;
            }
            return null;
        }

        #endregion

        #region public bool Session_GetUserToken(int id)
        public bool Session_GetUserToken(int id)
        {
            var getUserToken = toget.Sessions.Find(id);
            if (getUserToken.session_token != null)
            {
                if (session_flag == 1)
                {
                    return true;
                }
                else
                {
                    Session_Logout(id);
                }
            }
            else
            {
                session_flag = 0;
            }
            return false;
        }
        #endregion


        public bool DebugMode
        {
            get
            {
                if (DebugHelpers.ReadSetting("AppDebugMode") == "true")
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }


        #region public bool Session_Logout(int id)
        public bool Session_Logout(int id)
        {
            if (id != 0)
            {

                var session_logout_state = (from s in toget.Sessions
                                            where
                                                s.session_idPK == id
                                                && s.session_flag == 1
                                            select s).ToList().FirstOrDefault();
                if (session_logout_state != null)
                {
                    session_logout_state.session_flag = 0;
                    session_logout_state.session_datelogout = DateTime.Now.ToString("d/MM/yyyy");
                    session_logout_state.session_timeExpired = DateTime.Now.ToString("HH:mm:ss", System.Globalization.DateTimeFormatInfo.InvariantInfo);
                    toget.SaveChanges();
                    return true;
                }
            }
            return false;

        }
        #endregion


        #region public Guid EncryptSession_Token(string password)
        public Guid EncryptSession_Token(string password)
        {
            // Create a new instance of the MD5CryptoServiceProvider object.
            MD5 md5Hasher = MD5.Create();
            // Convert the input string to a byte array and compute the hash.
            byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(password));
            return new Guid(data);
        }
        #endregion

        #region  public int LogIn_Auth(string username, string pssword)
        public int LogIn_Auth(string username, string pssword)
        {

            var acc = (from user in toget.Users
                       where user.user_name == username || user.password == pssword
                       select user).SingleOrDefault();

            if (acc != null)
            {
                if (acc.user_name == username || acc.password == pssword)
                {
                    ctr = 0;
                    return ctr;
                }
            }
            times = ctr + 1;
            ctr += 1;
            return ctr;
        }
        #endregion

    }
}